#include "stdafx.h"
#include "control_internal_amimations.h"
#include "ui_multi_timer.h"

_SSL_BEGIN
_SSUIL_BEGIN

UIControlInternalAnimationBase::UIControlInternalAnimationBase()
{
	timer_id_ = 0;
	step_cnt_ = 30;
	step_now_ = 0;
}

UIControlInternalAnimationBase::~UIControlInternalAnimationBase()
{

}

bool UIControlInternalAnimationBase::StartAnimate(IUIControlInterface *control)
{
	if(control == NULL)
		return false;
	ui_manager_ = control->GetWindowManager();
	if(ui_manager_ == NULL)
		return false;

	UIMultiTimer *multi_timer = dynamic_cast<UIMultiTimer*>(control);
	if(multi_timer == NULL)
		return false;
	control_ = control;
	if(timer_id_ != 0)
	{
		StopAnimation();
	}
	step_now_ = 0;
	timer_id_ = multi_timer->SetIDTimer(timer_id_, 20);
	SS_ASSERT(timer_id_ > 0);
	return true;
}

bool UIControlInternalAnimationBase::StopAnimation()
{
	if(control_ == NULL)
	{
		timer_id_ = 0;
		return true;
	}
	UIMultiTimer *multi_timer = dynamic_cast<UIMultiTimer*>(control_.get());
	if(multi_timer != NULL)
	{
		multi_timer->KillIDTimer(timer_id_);
	}
	timer_id_ = 0;
	control_ = NULL;
	return true;
}

unsigned int UIControlInternalAnimationBase::GetTimerID()
{
	return timer_id_;
}


UIControlInternalTransformAnimation::UIControlInternalTransformAnimation(const UIPoint &pt_start, const UIPoint &pt_end)
{
	pt_start_ = pt_start;
	pt_end_ = pt_end;
}

UIControlInternalTransformAnimation::~UIControlInternalTransformAnimation()
{

}


UIStepResult UIControlInternalTransformAnimation::DoAnimationStep()
{
	if(control_ == NULL)
		return kASFinish;

	step_now_++;

#define ROUND(x) (int)((x) > 0 ? (x) + 0.5 : (x) - 0.5)
	const int nMe = 2;
	double fAx = 2.f * (pt_end_.x - pt_start_.x) / pow((double)step_cnt_, nMe);
	double fAy = 2.f * (pt_end_.y -pt_start_.y) / pow((double)step_cnt_, nMe);
	double fV1 = fAx * step_cnt_;
	double fV2 = fAy * step_cnt_;
	fAx = -fAx;
	fAy = -fAy;
	double fStepX = fV1 * step_now_ + 0.5 * fAx * pow((double)step_now_, nMe);
	double fStepY = fV2 * step_now_ + 0.5 * fAy * pow((double)step_now_, nMe);
	int x = pt_start_.x + ROUND(fStepX);
	int y = pt_start_.y + ROUND(fStepY);

	UIPresetPosition prepos = control_->GetPresetPosition();
	prepos.SetLeft(x, true).SetTop(y, true);
	control_->SetPresetPosition(prepos);
	control_->SmartSetNeedUpdate(true);
	return step_now_ < step_cnt_ ? kASContinue : kASFinish;
}

UIControlInternalSizeAnimation::UIControlInternalSizeAnimation(const UISize &sz_start, const UISize &sz_end)
{
	sz_start_ = sz_start;
	sz_end_ = sz_end;
}

UIControlInternalSizeAnimation::~UIControlInternalSizeAnimation()
{

}

UIStepResult UIControlInternalSizeAnimation::DoAnimationStep()
{
	if(control_ == NULL)
		return kASFinish;

	step_now_++;

	double xoffset = static_cast<double>(sz_end_.cx - sz_start_.cx) * step_now_ / step_cnt_;
	double yoffset = static_cast<double>(sz_end_.cy - sz_start_.cy) * step_now_ / step_cnt_;

	UIPresetPosition prepos = control_->GetPresetPosition();
	prepos.SetWidth(sz_start_.cx + static_cast<int>(xoffset)).SetHeight(sz_start_.cy + static_cast<int>(yoffset));
	control_->SetPresetPosition(prepos);
	control_->SmartSetNeedUpdate(true);

	return step_now_ < step_cnt_ ? kASContinue : kASFinish;
}

_SSUIL_END
_SSL_END
